package com.tdcy.sys.util;

import java.io.File;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;

import com.tdcy.framework.config.CustomPropertyConfigurer;
import com.tdcy.framework.util.ContextUtils;

public class BackupAndRestore {
	private static String mysqlpath;
	private static String host;
	private static String port;
	private static String username;
	private static String password;
	private static String exportDatabaseName;
	private static String exportPath;
	
	static{
		CustomPropertyConfigurer ppc = ContextUtils.getBean("propertyConfigurer");
		Properties properties= ppc.getProperties();
		mysqlpath=properties.getProperty("jdbc.mysqlpath");
		host=properties.getProperty("jdbc.host");
		port=properties.getProperty("jdbc.port");
		username=properties.getProperty("jdbc.user");
		password=properties.getProperty("jdbc.pwd");
		exportDatabaseName=properties.getProperty("jdbc.exportDatabaseName");
		exportPath=properties.getProperty("jdbc.exportPath");
	}

	/**
	 * 获取备份文件信息
	 */
	public static List<Map<String,String>> getBackupList(){
		SimpleDateFormat dateformat=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		List<Map<String,String>> listfile=new ArrayList<Map<String,String>>();
		List<File> list= getFileSort(exportPath);
		DecimalFormat decimalFormat=new DecimalFormat("0.00");//构造方法的字符格式这里如果小数不足2位,会以0补足.
		for(File file:list){
			Map<String,String> map=new HashMap<String,String>();
			map.put("backupName", file.getName());
			map.put("size", decimalFormat.format(Float.parseFloat(file.length()+"")/1024/1024)+"M");
			map.put("backupdate", dateformat.format(new Date(file.lastModified()))); 
			map.put("backuppath", file.getPath());
			listfile.add(map);
		}
		return listfile;
	}
	/**
     * 获取目录下所有文件(按时间排序)
     * 
     * @param path
     * @return
     */
    private static List<File> getFileSort(String path) {
        List<File> list = getFiles(path, new ArrayList<File>());
        if (list != null && list.size() > 0) {
            Collections.sort(list, new Comparator<File>() {
                public int compare(File file, File newFile) {
                    if (file.lastModified() < newFile.lastModified()) {
                        return 1;
                    } else if (file.lastModified() == newFile.lastModified()) {
                        return 0;
                    } else {
                        return -1;
                    }
                }
            });
        }
        return list;
    }
    
    /**
     * 
     * 获取目录下所有文件
     * 
     * @param realpath
     * @param files
     * @return
     */
    private static List<File> getFiles(String realpath, List<File> files) {
        File realFile = new File(realpath);
        if (realFile.isDirectory()) {
            File[] subfiles = realFile.listFiles();
            for (File file : subfiles) {
                if (file.isDirectory()) {
                    getFiles(file.getAbsolutePath(), files);
                } else {
                    files.add(file);
                }
            }
        }
        return files;
    }
    /**
     * 删除备份文件
     * @param backfile
     * @return
     */
    public static void delteFile(String backfile){
    	String backFilePath =exportPath+"/"+backfile;//要备份的文件
    	//判断要备份的文件是否已存在
		File backFile = new File(backFilePath);
		if(backFile.exists()){
			backFile.delete();
		}
    }
	/**
	 * 根据路径生成备份数据库的Shell字符串
	 * @param targetName 要备份的对象名：只能为表名和数据库名称
	 * @return 实际执行的shell命令
	 */
	private static String getBackupShellString(String filepath){
		String OSType = System.getProperty("os.name");
		String shellStr = "";
		if(OSType.indexOf("Windows")!=-1){
			shellStr = mysqlpath+"\\bin\\mysqldump.exe "+exportDatabaseName+" -h "+host+" -P"+port+" -u"+username+" -p"+password+" --result-file="+filepath;
		}else{
			shellStr = mysqlpath+"\\bin\\mysqldump.exe -h "+host+" -P"+port+" -u"+username+" -p"+
					password+" --result-file="+filepath+" --default-character-set=utf-8 "+exportDatabaseName+" "+true;
		}
		return shellStr;
	}
	/**
	 * 备份数据库
	 * @param targetName 要备份的对象名：只能为表名和数据库名称
	 * @return 成功:TRUE 失败:FALSE
	 * 备份表直接备份在指定文件夹，备份库则按日期备份到指定的文件夹
	 * 1 备份数据库 2 备份表
	 */
	public static boolean backup(String backupname){
		String backFilePath = "";
		try {
			backFilePath =exportPath+"/"+backupname+".bak";//要备份的文件
			File backDir = new File(exportPath);
			if(!backDir.exists()){//存放库的文件夹不存在
				backDir.mkdirs();
			}
			//判断要备份的文件是否已存在
			File backFile = new File(backFilePath);
			if(backFile.exists()){
				backFile.delete();
			}
			Runtime runt = Runtime.getRuntime();
			Process proc = runt.exec(getBackupShellString(backFilePath));
			int tag = proc.waitFor();//等待进程终止
			if(tag==0){
				return true;
			}else{
				return false;
			}
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
		
	}
	/**
	 * 恢复数据库
	 * @param targetName 要备份的对象名：只能为表名和数据库名称
	 * @return 成功:TRUE 失败:FALSE
	 */
	public static boolean restore(String backfile){
		try {
			Runtime runt = Runtime.getRuntime();
			Process proc;
			String cmdtext = getRestoreShellString(backfile);
			if(System.getProperty("os.name").indexOf("Windows")!=-1){
				String[] cmd= { "cmd","/c",cmdtext};
				proc= runt.exec(cmd);
			}else{
				String[] cmd= { "sh","-c",cmdtext};
				proc = runt.exec(cmd);
			} 
			int tag = proc.waitFor();//等待进程终止
			System.out.println("进程返回值为tag:"+tag);
			if(tag==0){
				return true;
			}else{
				return false;
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return false;
	}
	/**
	 * 根据路径生成恢复数据库的Shell字符串
	 * @param targetName targetName 要还原的对象名：只能为表名和数据库名称
	 * @return 恢复数据时实际执行的shell
	 */	
	private static String getRestoreShellString(String backfile){
		String OSType = System.getProperty("os.name");
		String shellStr = "";
		String backFilePath =exportPath+"/"+backfile;
		if(OSType.indexOf("Windows")!=-1){
			shellStr =  "\""+mysqlpath+"\\bin\\mysql.exe\" -h "+host+" -P"+port+" -u"+username+" -p"+
					password+" "+exportDatabaseName +" < "+backFilePath;
		}else{
			shellStr =  "\""+mysqlpath+"//bin//mysql.exe\" -h "+host+" -P"+port+" -u"+username+" -p"+
					password+" --default-character-set=utf-8 "+exportDatabaseName +" < "+backFilePath;
		}
		System.out.println(shellStr);
		return shellStr;
	}
	
	public static File getBackupFile(String backfile){
		String backFilePath =exportPath+"/"+backfile;//要备份的文件
    	//判断要备份的文件是否已存在
		File backFile = new File(backFilePath);
		return backFile;
	}
}
